#define MAX_LIGHTS 8

#define DIRECTIONAL 1
#define POINT 2
#define SPOT 3



varying vec3 normal;
varying vec4 color;
uniform int lightCountInt;
uniform float lightCountFloat;

////////////////////////// shadows ////////////////////////////

uniform float shadowTransparency;

//////////////////// shadow map shadows ///////////////////////

uniform bool mapShadow;
varying vec4 shadowTexCoord[MAX_LIGHTS];
uniform sampler2DShadow shadowMaps[MAX_LIGHTS];





////////////////////////// shading ////////////////////////////


varying vec3 lightDirection[MAX_LIGHTS];
uniform int lightType[MAX_LIGHTS];


//////////////////////////// cel /////////////////////////////


uniform bool cel;
uniform sampler2D lookUpTable;
uniform bool useLookUpTable;






void main(){

  vec3 lightDir;
  vec3 norm= normalize(normal);	


  ////////////////////////// shadows ////////////////////////////

  float shadow= 1.0;
  float shadows= 0.0;

  //////////////////// shadow map shadows ///////////////////////

  if(mapShadow){

    for(int i= 0; i<MAX_LIGHTS; i++){	
      if(i<lightCountInt && (lightType[i] == DIRECTIONAL || lightType[i] == SPOT)){
         lightDir= normalize(lightDirection[i]);	  
         shadow= shadow2DProj(shadowMaps[i], shadowTexCoord[i]).x;
	 if(dot(lightDir, norm)<0.3) shadow= 0.0;    
         if(shadow<1.0){ 
         shadows++;
    
	}	  
      }
    }
    if(shadows>0.0){ 
      shadow= shadowTransparency/shadows;
    }
    else shadow= 1.0;
  }	   




////////////////////////// shading ///////////////////////////

  vec3 shading= vec3(1.0);
  vec4 lightColor;		

//////////////////////////// cel /////////////////////////////

	

  if(cel){
   
    float intensity= 0.0;	
    for(int i= 0; i<MAX_LIGHTS; i++){
	
      if(i<lightCountInt && (lightType[i] == DIRECTIONAL || lightType[i] == POINT || lightType[i] == SPOT)){
	
 	lightDir= normalize(lightDirection[i]);	
	lightColor= gl_LightSource[i].diffuse;
  
        if(lightType[i]==SPOT){
	  float spot= dot(-lightDir, gl_LightSource[i].spotDirection);
	  if (spot > gl_LightSource[i].spotCosCutoff){   
	    intensity+= max(dot(lightDir, norm),0.0)*
	                ((lightColor.r+lightColor.g+lightColor.b)/3.0);
	  }
	}
	else intensity+= max(dot(lightDir, norm),0.0)*
	     		 ((lightColor.r+lightColor.g+lightColor.b)/3.0);
      }
    }
    if(mapShadow && shadow!=1.0){	
      intensity*= ((lightCountFloat-(shadowTransparency/shadow))/lightCountFloat);
    }
    intensity= min(intensity, 0.996);	
    if(useLookUpTable)
      shading= texture2D(lookUpTable, vec2(intensity, 0)).rgb;
    else shading= vec3(intensity);
  }

  gl_FragColor=vec4(color.rgb*shading*shadow, color.a);
}
